1 Set-up

1.1 Environment

if(!dir.exists("graphics")) {
    dir.create("graphics", showWarnings = FALSE, recursive = TRUE)
}

1.2 libs

suppressPackageStartupMessages({
    library(tidyverse)
    library(lubridate)
    library(broom)
    library(psych)
    #library(heatmaply)
    library(patchwork)
    library(ComplexHeatmap)
    library(circlize)
})

1.3 Data Read-In

1.3.1 tRNA array probes

tRNAprobes <- 
read_delim( 
    delim = "\t",
    file = "../tRNA-GtRNAdb/450k_coresponding_hg19tRNAs.bed",
    col_types = "ciicciiciciicccc",
    col_names = c("pChr","pStart","pEnd","probeID",
        as.character(
            read_delim(
                delim = "\t",
                file = "../tRNA-GtRNAdb/std_tRNA_header.txt",
                col_names = FALSE,
                col_types = paste0(rep("c",12),collapse = "")
            )
        )
    )
)

1.3.2 tRNAge gene set

tRNAge <- read_delim(
    delim = "\t",
     col_names = "tRNAname",
     col_types = "c",
     file = "../tRNA-GtRNAdb/GenWideSigWintRNAs.txt"
) %>%
    pull()

tRNAgeBB <- read_delim(
    delim = "\t",
     col_names = "tRNAname",
     col_types = "c",
     file = "../tRNA-GtRNAdb/BB_GWS_tRNA.txt"
) %>%
    pull()

1.3.3 tRNA gene data

tRNA <- read.table("../tRNA-GtRNAdb/hg19-tRNAs-SeqStrPseu.bed") 

colnames(tRNA) <- 
c(
    as.character(
        read.table(
            "../tRNA-GtRNAdb/std_tRNA_header.txt",
            stringsAsFactors = FALSE
        )
    ),
    "pseudo","str","seq"
)

tRNA <- tRNA %>%
    extract(tRNAname,
            c("nmt","aa","codon"),
            "(\\w*)-?tRNA-(i?\\w{3})(?:\\w+)?-(\\w+)-",
            remove = FALSE
    )

1.3.4 Methylation Data

dataTest <- readRDS(
    file = "data/tRNAprobesNormCancerArrayPairs.Rds"
)
dataTest %>%  dplyr::as_tibble() %>% distinct(case_id,age) %>% nrow()
[1] 1075
range(dataTest$age)
[1] 15.36516 90.00060
tRNAmethCancerNormal <- dataTest %>% 
    unnest() %>% 
    as_tibble() %>%
    filter(sample_type %in% c("Solid Tissue Normal", "Primary Tumor")) %>%
    mutate(tRNAge = tRNAname %in% tRNAge) %>%
    filter(!is.na(Beta_value))
`cols` is now required.
Please use `cols = c(data)`

2 Clustering

#FF7f00 - orange High methylation
#800080 - purple middling
#0000CD - blue low meth
# black - NA

#ensmbl
#ffff00 - yellow low meth
#19ff00 - green middle
#0033cc - blue high meth

col_fun <- colorRamp2(c(0, 0.5, 1), c("#ffff00", "#19ff00", "#0033cc"))
#col_fun <- colorRamp2(c(0, 0.5, 1), c("#0000CD", "#800080", "#FF7f00"))
# na_col = "black"
# col = col_fun
#tRNAprobes
tRNAProbeLookUp <- 
tRNAmethCancerNormal %>% 
    dplyr::select(probeID,tRNAname) %>% 
    distinct()

tRNAProbeLookUpColour <- left_join(
    tRNAProbeLookUp,
    data.frame(
        "colour"=colorspace::rainbow_hcl(tRNAProbeLookUp$tRNAname %>% unique() %>% length()),
        "tRNAname"=tRNAProbeLookUp$tRNAname %>% unique()
    ),
    by="tRNAname"
)
Column `tRNAname` joining character vector and factor, coercing into character vector
betasByTissue <- 
tRNAmethCancerNormal %>% 
    #head(n=1000) %>% 
    dplyr::select(probeID,primary_site,Beta_value) %>% 
    group_by(primary_site) %>%
    mutate(index = row_number()) %>%
    spread(primary_site,Beta_value) %>%
    dplyr::select(-index)

betasByTissueM <- 
betasByTissue %>% dplyr::select(-probeID) %>% as.matrix()
rownames(betasByTissueM) <- betasByTissue$probeID

2.1 Cancer and Normal By Probe

betasByTissueX <- 
tRNAmethCancerNormal %>% 
    #head(n=1000) %>% 
    dplyr::select(probeID,primary_site,Beta_value) %>% 
    group_by(primary_site) %>%
    mutate(index = row_number()) %>%
    spread(primary_site,Beta_value) %>%
    dplyr::select(-index) #%>%
    #as.matrix() 
meanBetasByTissue <- 
betasByTissueX %>% 
    group_by(probeID) %>%
    summarise_all(mean,na.rm=TRUE)


meanBetasByTissueM <- 
meanBetasByTissue %>% 
    dplyr::select(-probeID) %>% 
    as.matrix()
rownames(meanBetasByTissueM) <- meanBetasByTissue$probeID
meanBetasByTissueM <- meanBetasByTissueM %>% na.omit()

# tmp <- tRNAProbeLookUpColour %>% 
#       dplyr::filter(probeID %in% rownames(meanBetasByTissueM)) %>% 
#       pull(colour)
# names(tmp) <- tRNAProbeLookUpColour %>% 
#       dplyr::filter(probeID %in% rownames(meanBetasByTissueM)) %>% 
#       pull(tRNAname)
# tmp <- tmp %>% as.factor()

tmp <- tRNAProbeLookUpColour$colour
names(tmp) <- tRNAProbeLookUpColour$probeID 

heatmaply::heatmaply(
    meanBetasByTissueM#,
    # row_side_colors = rownames(meanBetasByTissueM),
    # row_side_palette = #tmp,
    
    #RowSideColors = tmp
        # tRNAProbeLookUpColour %>% 
        # dplyr::filter(probeID %in% rownames(meanBetasByTissueM)) %>% 
        # pull(colour)
)
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'

#heatmaply::heatmapr(meanBetasByTissueM)
# meanBetasByTissueMna <- 
# meanBetasByTissue %>% 
#   dplyr::select(-probeID) %>% 
#   as.matrix()
# rownames(meanBetasByTissueMna) <- meanBetasByTissue$probeID
# 
# heatmaply_na(meanBetasByTissueMna) # !!!

2.2 Cancer and Normal by tRNA

betasByTissueT <- 
tRNAmethCancerNormal %>% 
    #head(n=1000) %>% 
    dplyr::select(probeID,tRNAname,primary_site,Beta_value) %>% 
    group_by(primary_site) %>%
    mutate(index = row_number()) %>%
    spread(primary_site,Beta_value) %>%
    dplyr::select(-index) #%>%
    #as.matrix() 
meanBetasByTissueT <- 
betasByTissueT %>% 
    dplyr::select(-probeID) %>%
    group_by(tRNAname) %>%
    summarise_all(mean,na.rm=TRUE)


meanBetasByTissueTM <- 
meanBetasByTissueT %>% 
    dplyr::select(-tRNAname) %>% 
    as.matrix()
rownames(meanBetasByTissueTM) <- meanBetasByTissueT$tRNAname
meanBetasByTissueTM <- meanBetasByTissueTM %>% na.omit()

heatmaply::heatmaply(
    meanBetasByTissueTM,
    main = "Mean methylation by tRNA across Cancer and Normal Samples",
    limits=c(0,1)
)
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'

#heatmaply::heatmapr(meanBetasByTissueM)

meanBetasByTissueTMHeatmap <- 
meanBetasByTissueTM %>%
Heatmap(
    heatmap_width = unit(5.5,"inches"),
    heatmap_height = unit(7.5,"inches"),
    column_title_gp = gpar(fontsize = 16, fontface = "bold"),
    column_title = "Mean methylation by tRNA\nCombined Cancer and Normal Samples",
    name = "Meth",
    column_names_rot = 45,
    column_names_gp = gpar(fontsize = 10),
    row_names_gp = gpar(
        fontsize = 10,
        col = if_else(rownames(.) %in% tRNAgeBB,"red","black")
    ),
    na_col = "black",
    col = col_fun,
    row_title = "tRNA gene"
)


png(
    filename = "graphics/meanBetasByTissueTMHeatmap.png",
    width = 7, height = 8, units = "in", res = 192
)
meanBetasByTissueTMHeatmap
dev.off()
jpeg 
   2 
meanBetasByTissueTMHeatmap

meanBetasByTissueTMaaSplitHeatmap <- 
meanBetasByTissueTM %>%
Heatmap(
    #col = methColFunc,
    heatmap_width = unit(5.5,"inches"),
    heatmap_height = unit(7.5,"inches"),
    column_title_gp = gpar(fontsize = 16, fontface = "bold"),
    column_title = "Mean methylation by tRNA\nCombined Cancer and Normal Samples",
    name = "Meth",
    column_names_rot = 45,
    column_names_gp = gpar(fontsize = 10),
    row_split = rownames(.) %>%
        gsub(pattern = "tRNA-(\\w+)-\\w+-\\w+-\\d+",replacement = "\\1"),
    row_names_gp = gpar(
        fontsize = 10,
        col = if_else(rownames(.) %in% tRNAgeBB,"red","black")
    ),
    na_col = "black",
    col = col_fun,
    row_title = "tRNA gene"
)

png(
    filename = "graphics/meanBetasByTissueTMaaSplitHeatmap.png",
    width = 7, height = 8, units = "in", res = 192
)
meanBetasByTissueTMaaSplitHeatmap
dev.off()
jpeg 
   2 
meanBetasByTissueTMaaSplitHeatmap

2.3 Cancer by tRNA

betasByTissueTC <- 
tRNAmethCancerNormal %>% 
    dplyr::filter(sample_type == "Primary Tumor") %>%
    #head(n=1000) %>% 
    dplyr::select(probeID,tRNAname,primary_site,Beta_value) %>% 
    group_by(primary_site) %>%
    mutate(index = row_number()) %>%
    spread(primary_site,Beta_value) %>%
    dplyr::select(-index) #%>%
    #as.matrix() 
meanBetasByTissueTC <- 
betasByTissueTC %>% 
    dplyr::select(-probeID) %>%
    group_by(tRNAname) %>%
    summarise_all(mean,na.rm=TRUE)


meanBetasByTissueTCM <- 
meanBetasByTissueTC %>% 
    dplyr::select(-tRNAname) %>% 
    as.matrix()
rownames(meanBetasByTissueTCM) <- meanBetasByTissueTC$tRNAname
meanBetasByTissueTCM <- meanBetasByTissueTCM %>% na.omit()

heatmaply::heatmaply(
    meanBetasByTissueTCM,
    main = "Mean methylation by tRNA In Primary Tumour Samples",
    limits=c(0,1)
)
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'

#heatmaply::heatmapr(meanBetasByTissueM)

meanBetasByTissueTCMHeatmap <- 
meanBetasByTissueTCM %>%
Heatmap(
    heatmap_width = unit(5.5,"inches"),
    heatmap_height = unit(7.5,"inches"),
    column_title_gp = gpar(fontsize = 16, fontface = "bold"),
    column_title = "Mean methylation by tRNA\nIn Primary Tumour Samples",
    name = "Meth",
    column_names_rot = 45,
    column_names_gp = gpar(fontsize = 10),
    row_names_gp = gpar(
        fontsize = 10,
        col = if_else(rownames(.) %in% tRNAgeBB,"red","black")
    ),
    na_col = "black",
    col = col_fun,
    row_title = "tRNA gene"
)


png(
    filename = "graphics/meanBetasByTissueTCMHeatmap.png",
    width = 7, height = 8, units = "in", res = 192
)
meanBetasByTissueTCMHeatmap
dev.off()
jpeg 
   2 
meanBetasByTissueTCMHeatmap

meanBetasByTissueTCMaaSplitHeatmap <- 
meanBetasByTissueTCM %>%
Heatmap(
    #col = methColFunc,
    heatmap_width = unit(5.5,"inches"),
    heatmap_height = unit(7.5,"inches"),
    column_title_gp = gpar(fontsize = 16, fontface = "bold"),
    column_title = "Mean methylation by tRNA\nIn Primary Tumour Samples",
    name = "Meth",
    column_names_rot = 45,
    column_names_gp = gpar(fontsize = 10),
    row_split = rownames(.) %>%
        gsub(pattern = "tRNA-(\\w+)-\\w+-\\w+-\\d+",replacement = "\\1"),
    row_names_gp = gpar(
        fontsize = 10,
        col = if_else(rownames(.) %in% tRNAgeBB,"red","black")
    ),
    na_col = "black",
    col = col_fun,
    row_title = "tRNA gene"
)

png(
    filename = "graphics/meanBetasByTissueTCMaaSplitHeatmap.png",
    width = 7, height = 8, units = "in", res = 192
)
meanBetasByTissueTCMaaSplitHeatmap
dev.off()
jpeg 
   2 
meanBetasByTissueTCMaaSplitHeatmap

2.4 Normal by tRNA

betasByTissueTN <- 
tRNAmethCancerNormal %>% 
    dplyr::filter(sample_type == "Solid Tissue Normal") %>%
    #head(n=1000) %>% 
    dplyr::select(probeID,tRNAname,primary_site,Beta_value) %>% 
    group_by(primary_site) %>%
    mutate(index = row_number()) %>%
    spread(primary_site,Beta_value) %>%
    dplyr::select(-index) #%>%
    #as.matrix() 
meanBetasByTissueTN <- 
betasByTissueTN %>% 
    dplyr::select(-probeID) %>%
    group_by(tRNAname) %>%
    summarise_all(mean,na.rm=TRUE)


meanBetasByTissueTNM <- 
meanBetasByTissueTN %>% 
    dplyr::select(-tRNAname) %>% 
    as.matrix()
rownames(meanBetasByTissueTNM) <- meanBetasByTissueTN$tRNAname
meanBetasByTissueTNM <- meanBetasByTissueTNM %>% na.omit()

heatmaply::heatmaply(
    meanBetasByTissueTNM,
    main = "Mean methylation by tRNA In Solid Tissue Normal Samples",
    limits=c(0,1)
)
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'

#heatmaply::heatmapr(meanBetasByTissueM)
#tRNAgeBB
#methColFunc <- circlize::colorRamp2(c(0,0.5,1),c("blue","white","orange"))
meanBetasByTissueTNMHeatmap <- 
meanBetasByTissueTNM %>%
Heatmap(
    heatmap_width = unit(5.5,"inches"),
    heatmap_height = unit(7.5,"inches"),
    column_title_gp = gpar(fontsize = 16, fontface = "bold"),
    column_title = "Mean methylation by tRNA\nIn Solid Tissue Normal Samples",
    name = "Meth",
    column_names_rot = 45,
    column_names_gp = gpar(fontsize = 10),
    row_names_gp = gpar(
        fontsize = 10,
        col = if_else(rownames(.) %in% tRNAgeBB,"red","black")
    ),
    na_col = "black",
    col = col_fun,
    row_title = "tRNA gene"
)

png(
    filename = "graphics/meanBetasByTissueTNMHeatmap.png",
    width = 7, height = 8, units = "in", res = 192
)
meanBetasByTissueTNMHeatmap
dev.off()
null device 
          1 
meanBetasByTissueTNMHeatmap

meanBetasByTissueTNMaaSplitHeatmap <- 
meanBetasByTissueTNM %>%
Heatmap(
    #col = methColFunc,
    heatmap_width = unit(5.5,"inches"),
    heatmap_height = unit(7.5,"inches"),
    column_title_gp = gpar(fontsize = 16, fontface = "bold"),
    column_title = "Mean methylation by tRNA\nIn Solid Tissue Normal Samples",
    name = "Meth",
    column_names_rot = 45,
    column_names_gp = gpar(fontsize = 10),
    row_split = rownames(.) %>%
        gsub(pattern = "tRNA-(\\w+)-\\w+-\\w+-\\d+",replacement = "\\1"),
    row_names_gp = gpar(
        fontsize = 10,
        col = if_else(rownames(.) %in% tRNAgeBB,"red","black")
    ),
    na_col = "black",
    col = col_fun,
    row_title = "tRNA gene"
)

png(
    filename = "graphics/meanBetasByTissueTNMaaSplitHeatmap.png",
    width = 7, height = 8, units = "in", res = 192
)
meanBetasByTissueTNMaaSplitHeatmap
dev.off()
null device 
          1 
meanBetasByTissueTNMaaSplitHeatmap

pseudoSplit <- tRNA$pseudo
names(pseudoSplit) <- tRNA$tRNAname

meanBetasByTissueTNMpseudoSplitHeatmap <- 
meanBetasByTissueTNM %>%
Heatmap(
    #col = methColFunc,
    heatmap_width = unit(5.5,"inches"),
    heatmap_height = unit(7.5,"inches"),
    column_title_gp = gpar(fontsize = 16, fontface = "bold"),
    column_title = "Mean methylation by tRNA\nIn Solid Tissue Normal Samples",
    name = "Meth",
    column_names_rot = 45,
    column_names_gp = gpar(fontsize = 10),
    row_split = pseudoSplit[rownames(.)],
    row_names_gp = gpar(
        fontsize = 10,
        col = if_else(rownames(.) %in% tRNAgeBB,"red","black")
    ),
    na_col = "black",
    col = col_fun,
    row_title = "tRNA gene"
)

png(
    filename = "graphics/meanBetasByTissueTNMpseudoSplitHeatmap.png",
    width = 7, height = 8, units = "in", res = 192
)
meanBetasByTissueTNMpseudoSplitHeatmap
dev.off()
null device 
          1 
meanBetasByTissueTNMpseudoSplitHeatmap

meanBetasByTissueTNM %>% dim()
[1] 43 19
#meanBetasByTissueTNM %>% rownames()

meanBetasByTissueTCM %>% dim()
[1] 42 19
#meanBetasByTissueTCM %>% rownames()
meanBetasByTissueTCMx <- meanBetasByTissueTNM[meanBetasByTissueTCM %>% rownames(),]
heatmaply::heatmaply(
    file = "graphics/changeDNANormCancerbytRNA.html",
    (meanBetasByTissueTCM - meanBetasByTissueTCMx),
    #(meanBetasByTissueTCM - meanBetasByTissueTCMx)/meanBetasByTissueTCMx,
    main = "Differnce between Mean methylation in Normal and Cancer Samples by tRNA (Cancer - Normal)",
    limits=c(-1,1)
)
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'
'heatmap' objects don't have these attributes: 'showlegend'
Valid attributes include:
'type', 'visible', 'opacity', 'name', 'uid', 'ids', 'customdata', 'meta', 'hoverinfo', 'hoverlabel', 'stream', 'transforms', 'uirevision', 'z', 'x', 'x0', 'dx', 'y', 'y0', 'dy', 'text', 'hovertext', 'transpose', 'xtype', 'ytype', 'zsmooth', 'connectgaps', 'xgap', 'ygap', 'zhoverformat', 'hovertemplate', 'zauto', 'zmin', 'zmax', 'zmid', 'colorscale', 'autocolorscale', 'reversescale', 'showscale', 'colorbar', 'coloraxis', 'xcalendar', 'ycalendar', 'xaxis', 'yaxis', 'idssrc', 'customdatasrc', 'metasrc', 'hoverinfosrc', 'zsrc', 'xsrc', 'ysrc', 'textsrc', 'hovertextsrc', 'hovertemplatesrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'

3 Variance

byVar <- function(x,name) {
    tRNAColc <- paste0("tRNA_",name)
    tRNACol <- sym(tRNAColc)
    varCol <- sym(paste0("var_",name))
    x %>%
        apply(1,var) %>% 
        as.data.frame() %>% 
        rownames_to_column(var = tRNAColc) %>% 
        rename(!!varCol := !!expr(.)) %>%
        arrange(desc(!!varCol)) %>%
        #mutate(!!tRNACol := as.factor(!!tRNACol)) %>%#as.ordered
        ggplot(aes(reorder(!!tRNACol,!!varCol),!!varCol)) + 
            geom_col() + 
            labs(
                x=name,
                y="variance"
            ) +
            coord_flip()
}

byVar(meanBetasByTissueTNM,"normal") + 
byVar(meanBetasByTissueTCM,"cancer") +
plot_annotation(title = "tRNAs by rank order of variance")

4 Session Info

sessionInfo()
R version 3.6.2 (2019-12-12)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.3 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so

locale:
 [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C               LC_TIME=en_GB.UTF-8       
 [4] LC_COLLATE=en_GB.UTF-8     LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8   
 [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C                  LC_ADDRESS=C              
[10] LC_TELEPHONE=C             LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] circlize_0.4.8       ComplexHeatmap_2.0.0 patchwork_0.0.1      psych_1.8.12        
 [5] broom_0.5.2          lubridate_1.7.4      forcats_0.4.0        stringr_1.4.0       
 [9] dplyr_0.8.3          purrr_0.3.3          readr_1.3.1          tidyr_1.0.0         
[13] tibble_2.1.3         ggplot2_3.2.1        tidyverse_1.2.1      testthat_2.3.0      
[17] devtools_2.2.1       usethis_1.5.1        reprex_0.3.0        

loaded via a namespace (and not attached):
  [1] colorspace_1.4-1    rjson_0.2.20        ellipsis_0.3.0      rprojroot_1.3-2    
  [5] GlobalOptions_0.1.1 base64enc_0.1-3     fs_1.3.1            clue_0.3-57        
  [9] rstudioapi_0.10     remotes_2.1.0       xml2_1.2.2          codetools_0.2-16   
 [13] mnormt_1.5-5        knitr_1.25          pkgload_1.0.2       zeallot_0.1.0      
 [17] jsonlite_1.6        Cairo_1.5-10        packrat_0.5.0       cluster_2.1.0      
 [21] png_0.1-7           shiny_1.4.0         compiler_3.6.2      httr_1.4.1         
 [25] backports_1.1.5     fastmap_1.0.1       assertthat_0.2.1    lazyeval_0.2.2     
 [29] cli_1.1.0           later_1.0.0         htmltools_0.4.0     prettyunits_1.0.2  
 [33] tools_3.6.2         gtable_0.3.0        glue_1.3.1          reshape2_1.4.3     
 [37] Rcpp_1.0.3          cellranger_1.1.0    vctrs_0.2.0         gdata_2.18.0       
 [41] nlme_3.1-143        crosstalk_1.0.0     iterators_1.0.12    xfun_0.10          
 [45] ps_1.3.0            rvest_0.3.5         mime_0.7            lifecycle_0.1.0    
 [49] gtools_3.8.1        dendextend_1.12.0   MASS_7.3-51.5       scales_1.0.0       
 [53] TSP_1.1-7           promises_1.1.0      hms_0.5.2           parallel_3.6.2     
 [57] RColorBrewer_1.1-2  yaml_2.2.0          memoise_1.1.0       heatmaply_0.16.0   
 [61] gridExtra_2.3       stringi_1.4.3       gclus_1.3.2         desc_1.2.0         
 [65] foreach_1.4.7       seriation_1.2-8     caTools_1.17.1.2    pkgbuild_1.0.6     
 [69] shape_1.4.4         rlang_0.4.1         pkgconfig_2.0.3     bitops_1.0-6       
 [73] evaluate_0.14       lattice_0.20-38     htmlwidgets_1.5.1   labeling_0.3       
 [77] processx_3.4.1      tidyselect_0.2.5    plyr_1.8.4          magrittr_1.5       
 [81] R6_2.4.0            gplots_3.0.1.1      generics_0.0.2      pillar_1.4.2       
 [85] haven_2.2.0         foreign_0.8-72      withr_2.1.2         modelr_0.1.5       
 [89] crayon_1.3.4        KernSmooth_2.23-16  plotly_4.9.1        rmarkdown_1.16     
 [93] viridis_0.5.1       GetoptLong_0.1.7    readxl_1.3.1        data.table_1.12.6  
 [97] callr_3.3.2         digest_0.6.22       webshot_0.5.1       xtable_1.8-4       
[101] httpuv_1.5.2        munsell_0.5.0       registry_0.5-1      viridisLite_0.3.0  
[105] sessioninfo_1.1.1  

5 References

LS0tCnRpdGxlOiAiMDMgLSBHZW5vbWljRGF0YUNvbW1vbnMgTm9ybWFsIFZzLiBDYW5jZXIgdGlzc3VlIHRSTkEgZ2VuZSBtZXRoeWxhdGlvbiAtIENsdXN0ZXJpbmciCmF1dGhvcjogIlJpY2hhcmQgSi4gQWN0b24iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICBodG1sX25vdGVib29rOgogICAgZmlnX2NhcHRpb246IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwpiaWJsaW9ncmFwaHk6ICJgciBub3JtYWxpemVQYXRoKCcuLi9saWJyYXJ5LmJpYicpYCIKLS0tCgojIFNldC11cAoKIyMgRW52aXJvbm1lbnQKCmBgYHtyfQppZighZGlyLmV4aXN0cygiZ3JhcGhpY3MiKSkgewoJZGlyLmNyZWF0ZSgiZ3JhcGhpY3MiLCBzaG93V2FybmluZ3MgPSBGQUxTRSwgcmVjdXJzaXZlID0gVFJVRSkKfQpgYGAKCiMjIGxpYnMKCmBgYHtyfQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoewoJbGlicmFyeSh0aWR5dmVyc2UpCglsaWJyYXJ5KGx1YnJpZGF0ZSkKCWxpYnJhcnkoYnJvb20pCglsaWJyYXJ5KHBzeWNoKQoJbGlicmFyeShoZWF0bWFwbHkpCglsaWJyYXJ5KHBhdGNod29yaykKCWxpYnJhcnkoQ29tcGxleEhlYXRtYXApCglsaWJyYXJ5KGNpcmNsaXplKQp9KQpgYGAKCiMjIERhdGEgUmVhZC1JbgoKIyMjIHRSTkEgYXJyYXkgcHJvYmVzCgpgYGB7cn0KdFJOQXByb2JlcyA8LSAKcmVhZF9kZWxpbSgJCglkZWxpbSA9ICJcdCIsCglmaWxlID0gIi4uL3RSTkEtR3RSTkFkYi80NTBrX2NvcmVzcG9uZGluZ19oZzE5dFJOQXMuYmVkIiwKCWNvbF90eXBlcyA9ICJjaWljY2lpY2ljaWljY2NjIiwKCWNvbF9uYW1lcyA9IGMoInBDaHIiLCJwU3RhcnQiLCJwRW5kIiwicHJvYmVJRCIsCgkJYXMuY2hhcmFjdGVyKAoJCQlyZWFkX2RlbGltKAoJCQkJZGVsaW0gPSAiXHQiLAoJCQkJZmlsZSA9ICIuLi90Uk5BLUd0Uk5BZGIvc3RkX3RSTkFfaGVhZGVyLnR4dCIsCgkJCQljb2xfbmFtZXMgPSBGQUxTRSwKCQkJCWNvbF90eXBlcyA9IHBhc3RlMChyZXAoImMiLDEyKSxjb2xsYXBzZSA9ICIiKQoJCQkpCgkJKQoJKQopCgpgYGAKCiMjIyB0Uk5BZ2UgZ2VuZSBzZXQKCmBgYHtyfQp0Uk5BZ2UgPC0gcmVhZF9kZWxpbSgKCWRlbGltID0gIlx0IiwKCSBjb2xfbmFtZXMgPSAidFJOQW5hbWUiLAoJIGNvbF90eXBlcyA9ICJjIiwKCSBmaWxlID0gIi4uL3RSTkEtR3RSTkFkYi9HZW5XaWRlU2lnV2ludFJOQXMudHh0IgopICU+JQoJcHVsbCgpCgp0Uk5BZ2VCQiA8LSByZWFkX2RlbGltKAoJZGVsaW0gPSAiXHQiLAoJIGNvbF9uYW1lcyA9ICJ0Uk5BbmFtZSIsCgkgY29sX3R5cGVzID0gImMiLAoJIGZpbGUgPSAiLi4vdFJOQS1HdFJOQWRiL0JCX0dXU190Uk5BLnR4dCIKKSAlPiUKCXB1bGwoKQpgYGAKCiMjIyB0Uk5BIGdlbmUgZGF0YQoKYGBge3J9CnRSTkEgPC0gcmVhZC50YWJsZSgiLi4vdFJOQS1HdFJOQWRiL2hnMTktdFJOQXMtU2VxU3RyUHNldS5iZWQiKSAKCmNvbG5hbWVzKHRSTkEpIDwtIApjKAoJYXMuY2hhcmFjdGVyKAoJCXJlYWQudGFibGUoCgkJCSIuLi90Uk5BLUd0Uk5BZGIvc3RkX3RSTkFfaGVhZGVyLnR4dCIsCgkJCXN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQoJCSkKCSksCgkicHNldWRvIiwic3RyIiwic2VxIgopCgp0Uk5BIDwtIHRSTkEgJT4lCglleHRyYWN0KHRSTkFuYW1lLAoJCQljKCJubXQiLCJhYSIsImNvZG9uIiksCgkJCSIoXFx3KiktP3RSTkEtKGk/XFx3ezN9KSg/OlxcdyspPy0oXFx3KyktIiwKCQkJcmVtb3ZlID0gRkFMU0UKCSkKCmBgYAoKIyMjIE1ldGh5bGF0aW9uIERhdGEKCmBgYHtyfQpkYXRhVGVzdCA8LSByZWFkUkRTKAoJZmlsZSA9ICJkYXRhL3RSTkFwcm9iZXNOb3JtQ2FuY2VyQXJyYXlQYWlycy5SZHMiCikKYGBgCgpgYGB7cn0KZGF0YVRlc3QgJT4lICBkcGx5cjo6YXNfdGliYmxlKCkgJT4lIGRpc3RpbmN0KGNhc2VfaWQsYWdlKSAlPiUgbnJvdygpCnJhbmdlKGRhdGFUZXN0JGFnZSkKYGBgCgpgYGB7cn0KdFJOQW1ldGhDYW5jZXJOb3JtYWwgPC0gZGF0YVRlc3QgJT4lIAoJdW5uZXN0KCkgJT4lIAoJYXNfdGliYmxlKCkgJT4lCglmaWx0ZXIoc2FtcGxlX3R5cGUgJWluJSBjKCJTb2xpZCBUaXNzdWUgTm9ybWFsIiwgIlByaW1hcnkgVHVtb3IiKSkgJT4lCgltdXRhdGUodFJOQWdlID0gdFJOQW5hbWUgJWluJSB0Uk5BZ2UpICU+JQoJZmlsdGVyKCFpcy5uYShCZXRhX3ZhbHVlKSkKCmBgYAoKIyBDbHVzdGVyaW5nCgpgYGB7cn0KI0ZGN2YwMCAtIG9yYW5nZSBIaWdoIG1ldGh5bGF0aW9uCiM4MDAwODAgLSBwdXJwbGUgbWlkZGxpbmcKIzAwMDBDRCAtIGJsdWUgbG93IG1ldGgKIyBibGFjayAtIE5BCgojZW5zbWJsCiNmZmZmMDAgLSB5ZWxsb3cgbG93IG1ldGgKIzE5ZmYwMCAtIGdyZWVuIG1pZGRsZQojMDAzM2NjIC0gYmx1ZSBoaWdoIG1ldGgKCmNvbF9mdW4gPC0gY29sb3JSYW1wMihjKDAsIDAuNSwgMSksIGMoIiNmZmZmMDAiLCAiIzE5ZmYwMCIsICIjMDAzM2NjIikpCiNjb2xfZnVuIDwtIGNvbG9yUmFtcDIoYygwLCAwLjUsIDEpLCBjKCIjMDAwMENEIiwgIiM4MDAwODAiLCAiI0ZGN2YwMCIpKQojIG5hX2NvbCA9ICJibGFjayIKIyBjb2wgPSBjb2xfZnVuCgpgYGAKCmBgYHtyfQojdFJOQXByb2Jlcwp0Uk5BUHJvYmVMb29rVXAgPC0gCnRSTkFtZXRoQ2FuY2VyTm9ybWFsICU+JSAKCWRwbHlyOjpzZWxlY3QocHJvYmVJRCx0Uk5BbmFtZSkgJT4lIAoJZGlzdGluY3QoKQoKdFJOQVByb2JlTG9va1VwQ29sb3VyIDwtIGxlZnRfam9pbigKCXRSTkFQcm9iZUxvb2tVcCwKCWRhdGEuZnJhbWUoCgkJImNvbG91ciI9Y29sb3JzcGFjZTo6cmFpbmJvd19oY2wodFJOQVByb2JlTG9va1VwJHRSTkFuYW1lICU+JSB1bmlxdWUoKSAlPiUgbGVuZ3RoKCkpLAoJCSJ0Uk5BbmFtZSI9dFJOQVByb2JlTG9va1VwJHRSTkFuYW1lICU+JSB1bmlxdWUoKQoJKSwKCWJ5PSJ0Uk5BbmFtZSIKKQpgYGAKCmBgYHtyfQpiZXRhc0J5VGlzc3VlIDwtIAp0Uk5BbWV0aENhbmNlck5vcm1hbCAlPiUgCgkjaGVhZChuPTEwMDApICU+JSAKCWRwbHlyOjpzZWxlY3QocHJvYmVJRCxwcmltYXJ5X3NpdGUsQmV0YV92YWx1ZSkgJT4lIAoJZ3JvdXBfYnkocHJpbWFyeV9zaXRlKSAlPiUKCW11dGF0ZShpbmRleCA9IHJvd19udW1iZXIoKSkgJT4lCglzcHJlYWQocHJpbWFyeV9zaXRlLEJldGFfdmFsdWUpICU+JQoJZHBseXI6OnNlbGVjdCgtaW5kZXgpCgpiZXRhc0J5VGlzc3VlTSA8LSAKYmV0YXNCeVRpc3N1ZSAlPiUgZHBseXI6OnNlbGVjdCgtcHJvYmVJRCkgJT4lIGFzLm1hdHJpeCgpCnJvd25hbWVzKGJldGFzQnlUaXNzdWVNKSA8LSBiZXRhc0J5VGlzc3VlJHByb2JlSUQKCmBgYAoKIyMgQ2FuY2VyIGFuZCBOb3JtYWwgQnkgUHJvYmUKCmBgYHtyLCBmaWcuaGVpZ2h0ID0gOCwgZmlnLndpZHRoID0gN30KYmV0YXNCeVRpc3N1ZVggPC0gCnRSTkFtZXRoQ2FuY2VyTm9ybWFsICU+JSAKCSNoZWFkKG49MTAwMCkgJT4lIAoJZHBseXI6OnNlbGVjdChwcm9iZUlELHByaW1hcnlfc2l0ZSxCZXRhX3ZhbHVlKSAlPiUgCglncm91cF9ieShwcmltYXJ5X3NpdGUpICU+JQoJbXV0YXRlKGluZGV4ID0gcm93X251bWJlcigpKSAlPiUKCXNwcmVhZChwcmltYXJ5X3NpdGUsQmV0YV92YWx1ZSkgJT4lCglkcGx5cjo6c2VsZWN0KC1pbmRleCkgIyU+JQoJI2FzLm1hdHJpeCgpIAptZWFuQmV0YXNCeVRpc3N1ZSA8LSAKYmV0YXNCeVRpc3N1ZVggJT4lIAoJZ3JvdXBfYnkocHJvYmVJRCkgJT4lCglzdW1tYXJpc2VfYWxsKG1lYW4sbmEucm09VFJVRSkKCgptZWFuQmV0YXNCeVRpc3N1ZU0gPC0gCm1lYW5CZXRhc0J5VGlzc3VlICU+JSAKCWRwbHlyOjpzZWxlY3QoLXByb2JlSUQpICU+JSAKCWFzLm1hdHJpeCgpCnJvd25hbWVzKG1lYW5CZXRhc0J5VGlzc3VlTSkgPC0gbWVhbkJldGFzQnlUaXNzdWUkcHJvYmVJRAptZWFuQmV0YXNCeVRpc3N1ZU0gPC0gbWVhbkJldGFzQnlUaXNzdWVNICU+JSBuYS5vbWl0KCkKCiMgdG1wIDwtIHRSTkFQcm9iZUxvb2tVcENvbG91ciAlPiUgCiMgCQlkcGx5cjo6ZmlsdGVyKHByb2JlSUQgJWluJSByb3duYW1lcyhtZWFuQmV0YXNCeVRpc3N1ZU0pKSAlPiUgCiMgCQlwdWxsKGNvbG91cikKIyBuYW1lcyh0bXApIDwtIHRSTkFQcm9iZUxvb2tVcENvbG91ciAlPiUgCiMgCQlkcGx5cjo6ZmlsdGVyKHByb2JlSUQgJWluJSByb3duYW1lcyhtZWFuQmV0YXNCeVRpc3N1ZU0pKSAlPiUgCiMgCQlwdWxsKHRSTkFuYW1lKQojIHRtcCA8LSB0bXAgJT4lIGFzLmZhY3RvcigpCgp0bXAgPC0gdFJOQVByb2JlTG9va1VwQ29sb3VyJGNvbG91cgpuYW1lcyh0bXApIDwtIHRSTkFQcm9iZUxvb2tVcENvbG91ciRwcm9iZUlEIAoKaGVhdG1hcGx5OjpoZWF0bWFwbHkoCgltZWFuQmV0YXNCeVRpc3N1ZU0jLAoJIyByb3dfc2lkZV9jb2xvcnMgPSByb3duYW1lcyhtZWFuQmV0YXNCeVRpc3N1ZU0pLAoJIyByb3dfc2lkZV9wYWxldHRlID0gI3RtcCwKCQoJI1Jvd1NpZGVDb2xvcnMgPSB0bXAKCQkjIHRSTkFQcm9iZUxvb2tVcENvbG91ciAlPiUgCgkJIyBkcGx5cjo6ZmlsdGVyKHByb2JlSUQgJWluJSByb3duYW1lcyhtZWFuQmV0YXNCeVRpc3N1ZU0pKSAlPiUgCgkJIyBwdWxsKGNvbG91cikKKQojaGVhdG1hcGx5OjpoZWF0bWFwcihtZWFuQmV0YXNCeVRpc3N1ZU0pCmBgYAoKYGBge3J9CiMgbWVhbkJldGFzQnlUaXNzdWVNbmEgPC0gCiMgbWVhbkJldGFzQnlUaXNzdWUgJT4lIAojIAlkcGx5cjo6c2VsZWN0KC1wcm9iZUlEKSAlPiUgCiMgCWFzLm1hdHJpeCgpCiMgcm93bmFtZXMobWVhbkJldGFzQnlUaXNzdWVNbmEpIDwtIG1lYW5CZXRhc0J5VGlzc3VlJHByb2JlSUQKIyAKIyBoZWF0bWFwbHlfbmEobWVhbkJldGFzQnlUaXNzdWVNbmEpICMgISEhCmBgYAoKIyMgQ2FuY2VyIGFuZCBOb3JtYWwgYnkgdFJOQQoKYGBge3IsIGZpZy5oZWlnaHQgPSA4LCBmaWcud2lkdGggPSA3fQpiZXRhc0J5VGlzc3VlVCA8LSAKdFJOQW1ldGhDYW5jZXJOb3JtYWwgJT4lIAoJI2hlYWQobj0xMDAwKSAlPiUgCglkcGx5cjo6c2VsZWN0KHByb2JlSUQsdFJOQW5hbWUscHJpbWFyeV9zaXRlLEJldGFfdmFsdWUpICU+JSAKCWdyb3VwX2J5KHByaW1hcnlfc2l0ZSkgJT4lCgltdXRhdGUoaW5kZXggPSByb3dfbnVtYmVyKCkpICU+JQoJc3ByZWFkKHByaW1hcnlfc2l0ZSxCZXRhX3ZhbHVlKSAlPiUKCWRwbHlyOjpzZWxlY3QoLWluZGV4KSAjJT4lCgkjYXMubWF0cml4KCkgCm1lYW5CZXRhc0J5VGlzc3VlVCA8LSAKYmV0YXNCeVRpc3N1ZVQgJT4lIAoJZHBseXI6OnNlbGVjdCgtcHJvYmVJRCkgJT4lCglncm91cF9ieSh0Uk5BbmFtZSkgJT4lCglzdW1tYXJpc2VfYWxsKG1lYW4sbmEucm09VFJVRSkKCgptZWFuQmV0YXNCeVRpc3N1ZVRNIDwtIAptZWFuQmV0YXNCeVRpc3N1ZVQgJT4lIAoJZHBseXI6OnNlbGVjdCgtdFJOQW5hbWUpICU+JSAKCWFzLm1hdHJpeCgpCnJvd25hbWVzKG1lYW5CZXRhc0J5VGlzc3VlVE0pIDwtIG1lYW5CZXRhc0J5VGlzc3VlVCR0Uk5BbmFtZQptZWFuQmV0YXNCeVRpc3N1ZVRNIDwtIG1lYW5CZXRhc0J5VGlzc3VlVE0gJT4lIG5hLm9taXQoKQoKaGVhdG1hcGx5OjpoZWF0bWFwbHkoCgltZWFuQmV0YXNCeVRpc3N1ZVRNLAoJbWFpbiA9ICJNZWFuIG1ldGh5bGF0aW9uIGJ5IHRSTkEgYWNyb3NzIENhbmNlciBhbmQgTm9ybWFsIFNhbXBsZXMiLAoJbGltaXRzPWMoMCwxKQopCiNoZWF0bWFwbHk6OmhlYXRtYXByKG1lYW5CZXRhc0J5VGlzc3VlTSkKCm1lYW5CZXRhc0J5VGlzc3VlVE1IZWF0bWFwIDwtIAptZWFuQmV0YXNCeVRpc3N1ZVRNICU+JQpIZWF0bWFwKAoJaGVhdG1hcF93aWR0aCA9IHVuaXQoNS41LCJpbmNoZXMiKSwKCWhlYXRtYXBfaGVpZ2h0ID0gdW5pdCg3LjUsImluY2hlcyIpLAoJY29sdW1uX3RpdGxlX2dwID0gZ3Bhcihmb250c2l6ZSA9IDE2LCBmb250ZmFjZSA9ICJib2xkIiksCgljb2x1bW5fdGl0bGUgPSAiTWVhbiBtZXRoeWxhdGlvbiBieSB0Uk5BXG5Db21iaW5lZCBDYW5jZXIgYW5kIE5vcm1hbCBTYW1wbGVzIiwKCW5hbWUgPSAiTWV0aCIsCgljb2x1bW5fbmFtZXNfcm90ID0gNDUsCgljb2x1bW5fbmFtZXNfZ3AgPSBncGFyKGZvbnRzaXplID0gMTApLAoJcm93X25hbWVzX2dwID0gZ3BhcigKCQlmb250c2l6ZSA9IDEwLAoJCWNvbCA9IGlmX2Vsc2Uocm93bmFtZXMoLikgJWluJSB0Uk5BZ2VCQiwicmVkIiwiYmxhY2siKQoJKSwKCW5hX2NvbCA9ICJibGFjayIsCgljb2wgPSBjb2xfZnVuLAoJcm93X3RpdGxlID0gInRSTkEgZ2VuZSIKKQoKCnBuZygKCWZpbGVuYW1lID0gImdyYXBoaWNzL21lYW5CZXRhc0J5VGlzc3VlVE1IZWF0bWFwLnBuZyIsCgl3aWR0aCA9IDcsIGhlaWdodCA9IDgsIHVuaXRzID0gImluIiwgcmVzID0gMTkyCikKbWVhbkJldGFzQnlUaXNzdWVUTUhlYXRtYXAKZGV2Lm9mZigpCgptZWFuQmV0YXNCeVRpc3N1ZVRNSGVhdG1hcAoKbWVhbkJldGFzQnlUaXNzdWVUTWFhU3BsaXRIZWF0bWFwIDwtIAptZWFuQmV0YXNCeVRpc3N1ZVRNICU+JQpIZWF0bWFwKAoJI2NvbCA9IG1ldGhDb2xGdW5jLAoJaGVhdG1hcF93aWR0aCA9IHVuaXQoNS41LCJpbmNoZXMiKSwKCWhlYXRtYXBfaGVpZ2h0ID0gdW5pdCg3LjUsImluY2hlcyIpLAoJY29sdW1uX3RpdGxlX2dwID0gZ3Bhcihmb250c2l6ZSA9IDE2LCBmb250ZmFjZSA9ICJib2xkIiksCgljb2x1bW5fdGl0bGUgPSAiTWVhbiBtZXRoeWxhdGlvbiBieSB0Uk5BXG5Db21iaW5lZCBDYW5jZXIgYW5kIE5vcm1hbCBTYW1wbGVzIiwKCW5hbWUgPSAiTWV0aCIsCgljb2x1bW5fbmFtZXNfcm90ID0gNDUsCgljb2x1bW5fbmFtZXNfZ3AgPSBncGFyKGZvbnRzaXplID0gMTApLAoJcm93X3NwbGl0ID0gcm93bmFtZXMoLikgJT4lCgkJZ3N1YihwYXR0ZXJuID0gInRSTkEtKFxcdyspLVxcdystXFx3Ky1cXGQrIixyZXBsYWNlbWVudCA9ICJcXDEiKSwKCXJvd19uYW1lc19ncCA9IGdwYXIoCgkJZm9udHNpemUgPSAxMCwKCQljb2wgPSBpZl9lbHNlKHJvd25hbWVzKC4pICVpbiUgdFJOQWdlQkIsInJlZCIsImJsYWNrIikKCSksCgluYV9jb2wgPSAiYmxhY2siLAoJY29sID0gY29sX2Z1biwKCXJvd190aXRsZSA9ICJ0Uk5BIGdlbmUiCikKCnBuZygKCWZpbGVuYW1lID0gImdyYXBoaWNzL21lYW5CZXRhc0J5VGlzc3VlVE1hYVNwbGl0SGVhdG1hcC5wbmciLAoJd2lkdGggPSA3LCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIsIHJlcyA9IDE5MgopCm1lYW5CZXRhc0J5VGlzc3VlVE1hYVNwbGl0SGVhdG1hcApkZXYub2ZmKCkKCm1lYW5CZXRhc0J5VGlzc3VlVE1hYVNwbGl0SGVhdG1hcApgYGAKCiMjIENhbmNlciBieSB0Uk5BCgpgYGB7cixmaWcuaGVpZ2h0PTgsZmlnLndpZHRoPTd9CmJldGFzQnlUaXNzdWVUQyA8LSAKdFJOQW1ldGhDYW5jZXJOb3JtYWwgJT4lIAoJZHBseXI6OmZpbHRlcihzYW1wbGVfdHlwZSA9PSAiUHJpbWFyeSBUdW1vciIpICU+JQoJI2hlYWQobj0xMDAwKSAlPiUgCglkcGx5cjo6c2VsZWN0KHByb2JlSUQsdFJOQW5hbWUscHJpbWFyeV9zaXRlLEJldGFfdmFsdWUpICU+JSAKCWdyb3VwX2J5KHByaW1hcnlfc2l0ZSkgJT4lCgltdXRhdGUoaW5kZXggPSByb3dfbnVtYmVyKCkpICU+JQoJc3ByZWFkKHByaW1hcnlfc2l0ZSxCZXRhX3ZhbHVlKSAlPiUKCWRwbHlyOjpzZWxlY3QoLWluZGV4KSAjJT4lCgkjYXMubWF0cml4KCkgCm1lYW5CZXRhc0J5VGlzc3VlVEMgPC0gCmJldGFzQnlUaXNzdWVUQyAlPiUgCglkcGx5cjo6c2VsZWN0KC1wcm9iZUlEKSAlPiUKCWdyb3VwX2J5KHRSTkFuYW1lKSAlPiUKCXN1bW1hcmlzZV9hbGwobWVhbixuYS5ybT1UUlVFKQoKCm1lYW5CZXRhc0J5VGlzc3VlVENNIDwtIAptZWFuQmV0YXNCeVRpc3N1ZVRDICU+JSAKCWRwbHlyOjpzZWxlY3QoLXRSTkFuYW1lKSAlPiUgCglhcy5tYXRyaXgoKQpyb3duYW1lcyhtZWFuQmV0YXNCeVRpc3N1ZVRDTSkgPC0gbWVhbkJldGFzQnlUaXNzdWVUQyR0Uk5BbmFtZQptZWFuQmV0YXNCeVRpc3N1ZVRDTSA8LSBtZWFuQmV0YXNCeVRpc3N1ZVRDTSAlPiUgbmEub21pdCgpCgpoZWF0bWFwbHk6OmhlYXRtYXBseSgKCW1lYW5CZXRhc0J5VGlzc3VlVENNLAoJbWFpbiA9ICJNZWFuIG1ldGh5bGF0aW9uIGJ5IHRSTkEgSW4gUHJpbWFyeSBUdW1vdXIgU2FtcGxlcyIsCglsaW1pdHM9YygwLDEpCikKI2hlYXRtYXBseTo6aGVhdG1hcHIobWVhbkJldGFzQnlUaXNzdWVNKQoKbWVhbkJldGFzQnlUaXNzdWVUQ01IZWF0bWFwIDwtIAptZWFuQmV0YXNCeVRpc3N1ZVRDTSAlPiUKSGVhdG1hcCgKCWhlYXRtYXBfd2lkdGggPSB1bml0KDUuNSwiaW5jaGVzIiksCgloZWF0bWFwX2hlaWdodCA9IHVuaXQoNy41LCJpbmNoZXMiKSwKCWNvbHVtbl90aXRsZV9ncCA9IGdwYXIoZm9udHNpemUgPSAxNiwgZm9udGZhY2UgPSAiYm9sZCIpLAoJY29sdW1uX3RpdGxlID0gIk1lYW4gbWV0aHlsYXRpb24gYnkgdFJOQVxuSW4gUHJpbWFyeSBUdW1vdXIgU2FtcGxlcyIsCgluYW1lID0gIk1ldGgiLAoJY29sdW1uX25hbWVzX3JvdCA9IDQ1LAoJY29sdW1uX25hbWVzX2dwID0gZ3Bhcihmb250c2l6ZSA9IDEwKSwKCXJvd19uYW1lc19ncCA9IGdwYXIoCgkJZm9udHNpemUgPSAxMCwKCQljb2wgPSBpZl9lbHNlKHJvd25hbWVzKC4pICVpbiUgdFJOQWdlQkIsInJlZCIsImJsYWNrIikKCSksCgluYV9jb2wgPSAiYmxhY2siLAoJY29sID0gY29sX2Z1biwKCXJvd190aXRsZSA9ICJ0Uk5BIGdlbmUiCikKCgpwbmcoCglmaWxlbmFtZSA9ICJncmFwaGljcy9tZWFuQmV0YXNCeVRpc3N1ZVRDTUhlYXRtYXAucG5nIiwKCXdpZHRoID0gNywgaGVpZ2h0ID0gOCwgdW5pdHMgPSAiaW4iLCByZXMgPSAxOTIKKQptZWFuQmV0YXNCeVRpc3N1ZVRDTUhlYXRtYXAKZGV2Lm9mZigpCgptZWFuQmV0YXNCeVRpc3N1ZVRDTUhlYXRtYXAKCm1lYW5CZXRhc0J5VGlzc3VlVENNYWFTcGxpdEhlYXRtYXAgPC0gCm1lYW5CZXRhc0J5VGlzc3VlVENNICU+JQpIZWF0bWFwKAoJI2NvbCA9IG1ldGhDb2xGdW5jLAoJaGVhdG1hcF93aWR0aCA9IHVuaXQoNS41LCJpbmNoZXMiKSwKCWhlYXRtYXBfaGVpZ2h0ID0gdW5pdCg3LjUsImluY2hlcyIpLAoJY29sdW1uX3RpdGxlX2dwID0gZ3Bhcihmb250c2l6ZSA9IDE2LCBmb250ZmFjZSA9ICJib2xkIiksCgljb2x1bW5fdGl0bGUgPSAiTWVhbiBtZXRoeWxhdGlvbiBieSB0Uk5BXG5JbiBQcmltYXJ5IFR1bW91ciBTYW1wbGVzIiwKCW5hbWUgPSAiTWV0aCIsCgljb2x1bW5fbmFtZXNfcm90ID0gNDUsCgljb2x1bW5fbmFtZXNfZ3AgPSBncGFyKGZvbnRzaXplID0gMTApLAoJcm93X3NwbGl0ID0gcm93bmFtZXMoLikgJT4lCgkJZ3N1YihwYXR0ZXJuID0gInRSTkEtKFxcdyspLVxcdystXFx3Ky1cXGQrIixyZXBsYWNlbWVudCA9ICJcXDEiKSwKCXJvd19uYW1lc19ncCA9IGdwYXIoCgkJZm9udHNpemUgPSAxMCwKCQljb2wgPSBpZl9lbHNlKHJvd25hbWVzKC4pICVpbiUgdFJOQWdlQkIsInJlZCIsImJsYWNrIikKCSksCgluYV9jb2wgPSAiYmxhY2siLAoJY29sID0gY29sX2Z1biwKCXJvd190aXRsZSA9ICJ0Uk5BIGdlbmUiCikKCnBuZygKCWZpbGVuYW1lID0gImdyYXBoaWNzL21lYW5CZXRhc0J5VGlzc3VlVENNYWFTcGxpdEhlYXRtYXAucG5nIiwKCXdpZHRoID0gNywgaGVpZ2h0ID0gOCwgdW5pdHMgPSAiaW4iLCByZXMgPSAxOTIKKQptZWFuQmV0YXNCeVRpc3N1ZVRDTWFhU3BsaXRIZWF0bWFwCmRldi5vZmYoKQoKbWVhbkJldGFzQnlUaXNzdWVUQ01hYVNwbGl0SGVhdG1hcApgYGAKCiMjIE5vcm1hbCBieSB0Uk5BCgpgYGB7cixmaWcuaGVpZ2h0PTgsZmlnLndpZHRoPTd9CmJldGFzQnlUaXNzdWVUTiA8LSAKdFJOQW1ldGhDYW5jZXJOb3JtYWwgJT4lIAoJZHBseXI6OmZpbHRlcihzYW1wbGVfdHlwZSA9PSAiU29saWQgVGlzc3VlIE5vcm1hbCIpICU+JQoJI2hlYWQobj0xMDAwKSAlPiUgCglkcGx5cjo6c2VsZWN0KHByb2JlSUQsdFJOQW5hbWUscHJpbWFyeV9zaXRlLEJldGFfdmFsdWUpICU+JSAKCWdyb3VwX2J5KHByaW1hcnlfc2l0ZSkgJT4lCgltdXRhdGUoaW5kZXggPSByb3dfbnVtYmVyKCkpICU+JQoJc3ByZWFkKHByaW1hcnlfc2l0ZSxCZXRhX3ZhbHVlKSAlPiUKCWRwbHlyOjpzZWxlY3QoLWluZGV4KSAjJT4lCgkjYXMubWF0cml4KCkgCm1lYW5CZXRhc0J5VGlzc3VlVE4gPC0gCmJldGFzQnlUaXNzdWVUTiAlPiUgCglkcGx5cjo6c2VsZWN0KC1wcm9iZUlEKSAlPiUKCWdyb3VwX2J5KHRSTkFuYW1lKSAlPiUKCXN1bW1hcmlzZV9hbGwobWVhbixuYS5ybT1UUlVFKQoKCm1lYW5CZXRhc0J5VGlzc3VlVE5NIDwtIAptZWFuQmV0YXNCeVRpc3N1ZVROICU+JSAKCWRwbHlyOjpzZWxlY3QoLXRSTkFuYW1lKSAlPiUgCglhcy5tYXRyaXgoKQpyb3duYW1lcyhtZWFuQmV0YXNCeVRpc3N1ZVROTSkgPC0gbWVhbkJldGFzQnlUaXNzdWVUTiR0Uk5BbmFtZQptZWFuQmV0YXNCeVRpc3N1ZVROTSA8LSBtZWFuQmV0YXNCeVRpc3N1ZVROTSAlPiUgbmEub21pdCgpCgpoZWF0bWFwbHk6OmhlYXRtYXBseSgKCW1lYW5CZXRhc0J5VGlzc3VlVE5NLAoJbWFpbiA9ICJNZWFuIG1ldGh5bGF0aW9uIGJ5IHRSTkEgSW4gU29saWQgVGlzc3VlIE5vcm1hbCBTYW1wbGVzIiwKCWxpbWl0cz1jKDAsMSkKKQojaGVhdG1hcGx5OjpoZWF0bWFwcihtZWFuQmV0YXNCeVRpc3N1ZU0pCiN0Uk5BZ2VCQgpgYGAKCmBgYHtyfQojbWV0aENvbEZ1bmMgPC0gY2lyY2xpemU6OmNvbG9yUmFtcDIoYygwLDAuNSwxKSxjKCJibHVlIiwid2hpdGUiLCJvcmFuZ2UiKSkKbWVhbkJldGFzQnlUaXNzdWVUTk1IZWF0bWFwIDwtIAptZWFuQmV0YXNCeVRpc3N1ZVROTSAlPiUKSGVhdG1hcCgKCWhlYXRtYXBfd2lkdGggPSB1bml0KDUuNSwiaW5jaGVzIiksCgloZWF0bWFwX2hlaWdodCA9IHVuaXQoNy41LCJpbmNoZXMiKSwKCWNvbHVtbl90aXRsZV9ncCA9IGdwYXIoZm9udHNpemUgPSAxNiwgZm9udGZhY2UgPSAiYm9sZCIpLAoJY29sdW1uX3RpdGxlID0gIk1lYW4gbWV0aHlsYXRpb24gYnkgdFJOQVxuSW4gU29saWQgVGlzc3VlIE5vcm1hbCBTYW1wbGVzIiwKCW5hbWUgPSAiTWV0aCIsCgljb2x1bW5fbmFtZXNfcm90ID0gNDUsCgljb2x1bW5fbmFtZXNfZ3AgPSBncGFyKGZvbnRzaXplID0gMTApLAoJcm93X25hbWVzX2dwID0gZ3BhcigKCQlmb250c2l6ZSA9IDEwLAoJCWNvbCA9IGlmX2Vsc2Uocm93bmFtZXMoLikgJWluJSB0Uk5BZ2VCQiwicmVkIiwiYmxhY2siKQoJKSwKCW5hX2NvbCA9ICJibGFjayIsCgljb2wgPSBjb2xfZnVuLAoJcm93X3RpdGxlID0gInRSTkEgZ2VuZSIKKQoKcG5nKAoJZmlsZW5hbWUgPSAiZ3JhcGhpY3MvbWVhbkJldGFzQnlUaXNzdWVUTk1IZWF0bWFwLnBuZyIsCgl3aWR0aCA9IDcsIGhlaWdodCA9IDgsIHVuaXRzID0gImluIiwgcmVzID0gMTkyCikKbWVhbkJldGFzQnlUaXNzdWVUTk1IZWF0bWFwCmRldi5vZmYoKQoKbWVhbkJldGFzQnlUaXNzdWVUTk1IZWF0bWFwCmBgYAoKYGBge3J9Cm1lYW5CZXRhc0J5VGlzc3VlVE5NYWFTcGxpdEhlYXRtYXAgPC0gCm1lYW5CZXRhc0J5VGlzc3VlVE5NICU+JQpIZWF0bWFwKAoJI2NvbCA9IG1ldGhDb2xGdW5jLAoJaGVhdG1hcF93aWR0aCA9IHVuaXQoNS41LCJpbmNoZXMiKSwKCWhlYXRtYXBfaGVpZ2h0ID0gdW5pdCg3LjUsImluY2hlcyIpLAoJY29sdW1uX3RpdGxlX2dwID0gZ3Bhcihmb250c2l6ZSA9IDE2LCBmb250ZmFjZSA9ICJib2xkIiksCgljb2x1bW5fdGl0bGUgPSAiTWVhbiBtZXRoeWxhdGlvbiBieSB0Uk5BXG5JbiBTb2xpZCBUaXNzdWUgTm9ybWFsIFNhbXBsZXMiLAoJbmFtZSA9ICJNZXRoIiwKCWNvbHVtbl9uYW1lc19yb3QgPSA0NSwKCWNvbHVtbl9uYW1lc19ncCA9IGdwYXIoZm9udHNpemUgPSAxMCksCglyb3dfc3BsaXQgPSByb3duYW1lcyguKSAlPiUKCQlnc3ViKHBhdHRlcm4gPSAidFJOQS0oXFx3KyktXFx3Ky1cXHcrLVxcZCsiLHJlcGxhY2VtZW50ID0gIlxcMSIpLAoJcm93X25hbWVzX2dwID0gZ3BhcigKCQlmb250c2l6ZSA9IDEwLAoJCWNvbCA9IGlmX2Vsc2Uocm93bmFtZXMoLikgJWluJSB0Uk5BZ2VCQiwicmVkIiwiYmxhY2siKQoJKSwKCW5hX2NvbCA9ICJibGFjayIsCgljb2wgPSBjb2xfZnVuLAoJcm93X3RpdGxlID0gInRSTkEgZ2VuZSIKKQoKcG5nKAoJZmlsZW5hbWUgPSAiZ3JhcGhpY3MvbWVhbkJldGFzQnlUaXNzdWVUTk1hYVNwbGl0SGVhdG1hcC5wbmciLAoJd2lkdGggPSA3LCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIsIHJlcyA9IDE5MgopCm1lYW5CZXRhc0J5VGlzc3VlVE5NYWFTcGxpdEhlYXRtYXAKZGV2Lm9mZigpCgptZWFuQmV0YXNCeVRpc3N1ZVROTWFhU3BsaXRIZWF0bWFwCmBgYAoKYGBge3IsZmlnLndpZHRoPTcsZmlnLmhlaWdodD03fQpwc2V1ZG9TcGxpdCA8LSB0Uk5BJHBzZXVkbwpuYW1lcyhwc2V1ZG9TcGxpdCkgPC0gdFJOQSR0Uk5BbmFtZQoKbWVhbkJldGFzQnlUaXNzdWVUTk1wc2V1ZG9TcGxpdEhlYXRtYXAgPC0gCm1lYW5CZXRhc0J5VGlzc3VlVE5NICU+JQpIZWF0bWFwKAoJI2NvbCA9IG1ldGhDb2xGdW5jLAoJaGVhdG1hcF93aWR0aCA9IHVuaXQoNS41LCJpbmNoZXMiKSwKCWhlYXRtYXBfaGVpZ2h0ID0gdW5pdCg3LjUsImluY2hlcyIpLAoJY29sdW1uX3RpdGxlX2dwID0gZ3Bhcihmb250c2l6ZSA9IDE2LCBmb250ZmFjZSA9ICJib2xkIiksCgljb2x1bW5fdGl0bGUgPSAiTWVhbiBtZXRoeWxhdGlvbiBieSB0Uk5BXG5JbiBTb2xpZCBUaXNzdWUgTm9ybWFsIFNhbXBsZXMiLAoJbmFtZSA9ICJNZXRoIiwKCWNvbHVtbl9uYW1lc19yb3QgPSA0NSwKCWNvbHVtbl9uYW1lc19ncCA9IGdwYXIoZm9udHNpemUgPSAxMCksCglyb3dfc3BsaXQgPSBwc2V1ZG9TcGxpdFtyb3duYW1lcyguKV0sCglyb3dfbmFtZXNfZ3AgPSBncGFyKAoJCWZvbnRzaXplID0gMTAsCgkJY29sID0gaWZfZWxzZShyb3duYW1lcyguKSAlaW4lIHRSTkFnZUJCLCJyZWQiLCJibGFjayIpCgkpLAoJbmFfY29sID0gImJsYWNrIiwKCWNvbCA9IGNvbF9mdW4sCglyb3dfdGl0bGUgPSAidFJOQSBnZW5lIgopCgpwbmcoCglmaWxlbmFtZSA9ICJncmFwaGljcy9tZWFuQmV0YXNCeVRpc3N1ZVROTXBzZXVkb1NwbGl0SGVhdG1hcC5wbmciLAoJd2lkdGggPSA3LCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIsIHJlcyA9IDE5MgopCm1lYW5CZXRhc0J5VGlzc3VlVE5NcHNldWRvU3BsaXRIZWF0bWFwCmRldi5vZmYoKQoKbWVhbkJldGFzQnlUaXNzdWVUTk1wc2V1ZG9TcGxpdEhlYXRtYXAKYGBgCgpgYGB7cn0KbWVhbkJldGFzQnlUaXNzdWVUTk0gJT4lIGRpbSgpCiNtZWFuQmV0YXNCeVRpc3N1ZVROTSAlPiUgcm93bmFtZXMoKQoKbWVhbkJldGFzQnlUaXNzdWVUQ00gJT4lIGRpbSgpCiNtZWFuQmV0YXNCeVRpc3N1ZVRDTSAlPiUgcm93bmFtZXMoKQpgYGAKCmBgYHtyLGZpZy5oZWlnaHQ9OCxmaWcud2lkdGg9N30KbWVhbkJldGFzQnlUaXNzdWVUQ014IDwtIG1lYW5CZXRhc0J5VGlzc3VlVE5NW21lYW5CZXRhc0J5VGlzc3VlVENNICU+JSByb3duYW1lcygpLF0KaGVhdG1hcGx5OjpoZWF0bWFwbHkoCglmaWxlID0gImdyYXBoaWNzL2NoYW5nZUROQU5vcm1DYW5jZXJieXRSTkEuaHRtbCIsCgkobWVhbkJldGFzQnlUaXNzdWVUQ00gLSBtZWFuQmV0YXNCeVRpc3N1ZVRDTXgpLAoJIyhtZWFuQmV0YXNCeVRpc3N1ZVRDTSAtIG1lYW5CZXRhc0J5VGlzc3VlVENNeCkvbWVhbkJldGFzQnlUaXNzdWVUQ014LAoJbWFpbiA9ICJEaWZmZXJuY2UgYmV0d2VlbiBNZWFuIG1ldGh5bGF0aW9uIGluIE5vcm1hbCBhbmQgQ2FuY2VyIFNhbXBsZXMgYnkgdFJOQSAoQ2FuY2VyIC0gTm9ybWFsKSIsCglsaW1pdHM9YygtMSwxKQopCmBgYAoKIyBWYXJpYW5jZQoKYGBge3IsIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA3fQpieVZhciA8LSBmdW5jdGlvbih4LG5hbWUpIHsKCXRSTkFDb2xjIDwtIHBhc3RlMCgidFJOQV8iLG5hbWUpCgl0Uk5BQ29sIDwtIHN5bSh0Uk5BQ29sYykKCXZhckNvbCA8LSBzeW0ocGFzdGUwKCJ2YXJfIixuYW1lKSkKCXggJT4lCgkJYXBwbHkoMSx2YXIpICU+JSAKCQlhcy5kYXRhLmZyYW1lKCkgJT4lIAoJCXJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSB0Uk5BQ29sYykgJT4lIAoJCXJlbmFtZSghIXZhckNvbCA6PSAhIWV4cHIoLikpICU+JQoJCWFycmFuZ2UoZGVzYyghIXZhckNvbCkpICU+JQoJCSNtdXRhdGUoISF0Uk5BQ29sIDo9IGFzLmZhY3RvcighIXRSTkFDb2wpKSAlPiUjYXMub3JkZXJlZAoJCWdncGxvdChhZXMocmVvcmRlcighIXRSTkFDb2wsISF2YXJDb2wpLCEhdmFyQ29sKSkgKyAKCQkJZ2VvbV9jb2woKSArIAoJCQlsYWJzKAoJCQkJeD1uYW1lLAoJCQkJeT0idmFyaWFuY2UiCgkJCSkgKwoJCQljb29yZF9mbGlwKCkKfQoKYnlWYXIobWVhbkJldGFzQnlUaXNzdWVUTk0sIm5vcm1hbCIpICsgCmJ5VmFyKG1lYW5CZXRhc0J5VGlzc3VlVENNLCJjYW5jZXIiKSArCnBsb3RfYW5ub3RhdGlvbih0aXRsZSA9ICJ0Uk5BcyBieSByYW5rIG9yZGVyIG9mIHZhcmlhbmNlIikKYGBgCgojIFNlc3Npb24gSW5mbwoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgojIFJlZmVyZW5jZXMKCg==